/*********************************************************************************
Organization 					: 				Georgia Institute of Technology
  
Institute 						:				Cognitive Computing Group(CCL)
 
Authors							: 				Santiago Ontanon, Kinshuk Mishra
 												Neha Sugandh 
 												
Class							:				BuildBOPlan
 
Function						: 				Provides a Basic Operator Plan 
												for building a unit
****************************************************************************/
package planninglanguage.plans;

import mre.MRE;
import mre.ResourceAllocation;

import org.jdom.Element;

import planninglanguage.conditions.AndCondition;
import planninglanguage.conditions.BuildingCompleteCondition;
import planninglanguage.conditions.Condition;
import planninglanguage.conditions.GoldCondition;
import planninglanguage.conditions.OilCondition;
import planninglanguage.conditions.UnitExistsCondition;
import planninglanguage.conditions.UnitTypeExistsCondition;
import planninglanguage.conditions.WoodCondition;
import util.XMLWriter;
import base.ProxyBot;
import base.WargusStateImporter;

public class BuildBOPlan extends BasicOperatorPlan implements Cloneable{

	int m_x;
	int m_y;
	int m_buildType;
	int m_constructedUnitID;	// This stores which was the ID of the unit constructed in the expert's trace
	
	public BuildBOPlan(int a_unitID,int a_x,int a_y,int a_buildType,Condition a_precondition,Condition a_aliveCondition,Condition a_successCondition)
	{
		super(a_precondition,a_aliveCondition,a_successCondition);
		m_unitID=a_unitID;
		m_x=a_x;
		m_y=a_y;
		m_buildType = a_buildType;
		m_constructedUnitID = -1;

		m_precondition = new AndCondition(new UnitTypeExistsCondition("peasant",0),
										  new AndCondition(new GoldCondition(WargusStateImporter.unitCostGold(WargusStateImporter.unitTypeToString(m_buildType))),
												  		   new AndCondition(new WoodCondition(WargusStateImporter.unitCostWood(WargusStateImporter.unitTypeToString(m_buildType))),
												  				   			new OilCondition(WargusStateImporter.unitCostOil(WargusStateImporter.unitTypeToString(m_buildType))))));
		m_aliveCondition = new UnitExistsCondition(m_unitID);
		m_successCondition = new BuildingCompleteCondition(WargusStateImporter.unitTypeToString(m_buildType),m_x,m_y,0);
	}
	
	public BuildBOPlan(int a_unitID,int a_x,int a_y,int a_buildType,Condition a_precondition,Condition a_aliveCondition,Condition a_successCondition, Plan a_parent)
	{
		super(a_precondition,a_aliveCondition,a_successCondition);
		m_unitID=a_unitID;
		m_x=a_x;
		m_y=a_y;
		m_buildType = a_buildType;
		m_constructedUnitID = -1;

		m_precondition = new AndCondition(new UnitTypeExistsCondition("peasant",0),
										  new AndCondition(new GoldCondition(WargusStateImporter.unitCostGold(WargusStateImporter.unitTypeToString(m_buildType))),
												  		   new AndCondition(new WoodCondition(WargusStateImporter.unitCostWood(WargusStateImporter.unitTypeToString(m_buildType))),
												  				   			new OilCondition(WargusStateImporter.unitCostOil(WargusStateImporter.unitTypeToString(m_buildType))))));
		m_aliveCondition = new UnitExistsCondition(m_unitID);
		m_successCondition = new BuildingCompleteCondition(WargusStateImporter.unitTypeToString(m_buildType),m_x,m_y,0);
		m_parent = a_parent;
	}
	
	public Object clone()
	{
		BuildBOPlan l_p = new BuildBOPlan(m_unitID,m_x,m_y,m_buildType,null,null,null, m_parent);
		l_p.setContext(m_context);
		l_p.m_originalUnit = m_originalUnit;
		return l_p;
	}
	
	public int getX() {
		return m_x;
	}
	
	public int getY() {
		return m_y;
	}
	
	public int getBuildType(){
		return m_buildType;
	}
	
	public void setConstructedUnitID(int a_constructedUnitID) {
		m_constructedUnitID = a_constructedUnitID;
	}
	
	public int getConstructedUnitID() {
		return m_constructedUnitID;
	}

	public boolean send()
	{
		//send build command to ABL
		/*
		WargusInterface.m_action = WargusInterface.ACTION_BUILD;
		WargusInterface.m_unitid = m_unitID;
		WargusInterface.m_xmove = m_x;
		WargusInterface.m_ymove = m_y;
		WargusInterface.m_buildingtype = m_buildType;
		*/
		
	    ProxyBot.getProxyBot().build(m_unitID, m_x,m_y,false,m_buildType);
		
	    // If there are already resources allocated for the unit, deallocate them:
	    {
	    	ResourceAllocation r = null;
		    for(ResourceAllocation r2:MRE.allocated_resources) {
		    	if (r2.m_unitID == m_unitID) r = r2;
		    }
		    if (r!=null) {
		    	MRE.allocated_resources.remove(r);
				MRE.allocated_gold -= WargusStateImporter.unitCostGold(r.m_building);
				MRE.allocated_wood -= WargusStateImporter.unitCostWood(r.m_building);
				MRE.allocated_oil -= WargusStateImporter.unitCostOil(r.m_building);	    	
		    }
		}
	    MRE.allocated_resources.add(new ResourceAllocation((int)ProxyBot.getProxyBot().getCurrCycle(),WargusStateImporter.unitTypeToString(m_buildType),m_x,m_y,m_unitID));
		MRE.allocated_gold+=WargusStateImporter.unitCostGold((WargusStateImporter.unitTypeToString(m_buildType)));
		MRE.allocated_wood+=WargusStateImporter.unitCostWood((WargusStateImporter.unitTypeToString(m_buildType)));
		MRE.allocated_oil+=WargusStateImporter.unitCostOil((WargusStateImporter.unitTypeToString(m_buildType)));
		
		return true;
	}
	
	public String toString(int tabs) {
		String str= "";
		int i;
		
		for(i=0;i<tabs;i++) str = str + "  ";
		str = str + "BuildBOPlan(status = " + STATUS_NAME[m_status] + " , unitID = " + m_unitID + " x = " + m_x + " y = " + m_y + " , buildingType = " + m_buildType + " ) ";
		str = str + conditionsToString(tabs);
		return str;
	}	
	
	public boolean sameGoal(Object other)
	{
		if (getClass() != other.getClass()) return false;

		BuildBOPlan o = (BuildBOPlan) other;
		   
		if (m_unitID!=o.m_unitID) return false;		
		if (m_x!=o.m_x) return false;
		if (m_y!=o.m_y) return false;
		if (m_buildType!=o.m_buildType) return false;
		return true;
	}		
	
	public void writeXML(XMLWriter w) {
		w.tag(super.XMLopenTag() + " type=\"" + 
				this.getClass().getSimpleName() + "\"");		
		{
			w.tag(Plan.XML_X, m_x);
			w.tag(Plan.XML_Y, m_y);
			w.tag(Plan.XML_VALUE, WargusStateImporter.unitTypeToString(m_buildType));
			w.tag("constructed-unit-id", m_constructedUnitID);
			
			super.writeBOPlanAttrsXML(w);
		}
		w.tag(super.XMLcloseTag());
	}
	
	public static BuildBOPlan loadFromXML(Element e) {
		int x = Integer.parseInt(e.getChildText(Plan.XML_X));
		int y = Integer.parseInt(e.getChildText(Plan.XML_Y));
		int type = WargusStateImporter.unitTypeToInteger(e.getChildText(Plan.XML_VALUE));
		
		BuildBOPlan plan = new BuildBOPlan(-1, x, y, type, null, null, null);
		plan.setConstructedUnitID(Integer.parseInt(e.getChildText("constructed-unit-id")));		
		return plan;
	}
}